import { ArcRotateCamera, Color3, Color4, CubeTexture, Engine, HemisphericLight, LensFlare, LensFlareSystem, Mesh, MeshBuilder, Scene, SceneLoader, StandardMaterial, Texture, Vector3 } from "@babylonjs/core";

//镜头光晕(没搞懂)
export default class SkyBox {

    public engine: Engine;
    public scene: Scene;
    public canvas: HTMLCanvasElement;

    private updateAction: Map<number, (time: number) => {}> = new Map();
    private updateActionId: number = 0;

    public static skyBox: SkyBox;

    public constructor(canvas: HTMLCanvasElement) {
        this.canvas = canvas;
        this.engine = new Engine(canvas, true);
        this.scene = this.createScene();

        this.init();

        SkyBox.skyBox = this;
    }

    private init() {
        this.update(0);
    }

    private createScene() {
        const { engine, canvas } = this;
        let scene = new Scene(engine);
        scene.clearColor = new Color4(0, 0, 0, 1);

        const light = new HemisphericLight('defaultLight', new Vector3(1, 1, 0), scene);

        const camera = new ArcRotateCamera('Camera', Math.PI / 2, Math.PI / 3, 10, new Vector3(0, 0, 0), scene);
        camera.attachControl(canvas, true);


        SceneLoader.ImportMesh('', 'https://playground.babylonjs.com/scenes/', 'candle.babylon', scene, (meshes) => {
            scene.createDefaultEnvironment();//创建默认环境
            scene.getMeshByName('Plane')!.isVisible = false;

            //光晕
            const flarSystem = new LensFlareSystem('flarSystem', scene.getMeshByName('Cylinder_004'), scene);

            const url = 'https://playground.babylonjs.com/textures/';
            const flare00 = new LensFlare(0.1, 1, new Color3(1, 1, 1), url + 'flare.png', flarSystem);
            const flare01 = new LensFlare(0.15, 1.25, new Color3(0.95, 0.89, 0.72), url + 'flare.png', flarSystem);

        });



        return scene;
    }

    private update(time: number) {
        const { updateAction, scene } = this;
        updateAction.forEach((action, key) => {
            action(time);
        });
        scene.render();
        requestAnimationFrame((time) => {
            this.update(time);
        });
    }

    public setUpdateAction(action: (time: number) => {}, id: number = -1) {
        const { updateAction } = this;
        let curId = id;
        if (id == -1) {
            curId = this.updateActionId++;
        } else if (id >= this.updateActionId) {
            curId = this.updateActionId++;
        }
        updateAction.set(curId, action);
    }
}